#include <iostream>
#include <fstream>
#include <ctime>
#include <cstdlib>
#include "Sorter.h"
#include "StringSorter.h"
#include "DataWriter.h"

namespace {
	const int COMMAND_ARGUMENT_NUMBER = 5;
	const int DATA_TYPE_ARGUMENT = 1;
	const int SORT_MODE_ARGUMENT = 2;
	const int INPUT_FILE_ARGUMENT = 3;
	const int OUTPUT_FILE_ARGUMENT = 4;
}

void showUsage()
{
	std::cout <<"========================HELP========================" << std::endl;
	std::cout <<"Usage: filesort.exe -x -y inputFile outputFile"       << std::endl;
	std::cout <<"====================================================" << std::endl;
	std::cout <<"The parametr -x is a parametr of data type in file:"  << std::endl;
	std::cout <<"-i - the Integer type of data in file"                << std::endl;
	std::cout <<"-f - the Float type of data in  file"                 << std::endl;
	std::cout <<"-s - the Character type of data in file"              << std::endl;
	std::cout <<"====================================================" << std::endl;
	std::cout <<"The parametr -y is a parametr of data type in file:"  << std::endl;
	std::cout <<"-a - the Ascending type of sort"                      << std::endl;
	std::cout <<"-d - the Descending type of sort"                     << std::endl;
	std::cout <<"-r - the Random type of sort"                         << std::endl;
	std::cout <<"=====================N.TEREKHOV=====================" << std::endl;
}


template<class T>
void sortAndWrite(std::istream &inputStream, std::ostream& outputStream, CompareMode compMode) {
	Sorter<T> sorter;
	DataWriter<T> dataWriter;
	std::vector<T> result;
	
	sorter.sort(inputStream, compMode, result);
	dataWriter.writeData(result, outputStream);
}

int main(int argc, char **argv) {
	srand(static_cast<unsigned int>( time( NULL )));
	if( ::COMMAND_ARGUMENT_NUMBER != argc )
	{
		showUsage();
		return EXIT_FAILURE;
	}
	
	CompareMode sortMode;
	if( 0 == strcmp(argv[::SORT_MODE_ARGUMENT], "-a") ) {
		sortMode = ACSENDING;
	} else if ( 0 == strcmp(argv[::SORT_MODE_ARGUMENT], "-d") ) {
		sortMode = DESCENDING;
	} else if( 0 == strcmp(argv[::SORT_MODE_ARGUMENT], "-r") ) {
		sortMode = RANDOM;
	} else {
		std::cerr << "Unknown sort mode" << std::endl;
		return EXIT_FAILURE;
	}

	std::ifstream inputStream(argv[::INPUT_FILE_ARGUMENT]);
	if( !inputStream.is_open() ) {
		std::cerr << "Error open input file" << std::endl;
		return EXIT_FAILURE;
	}
	std::ofstream outputStream(argv[::OUTPUT_FILE_ARGUMENT], std::fstream::out);
	if( !outputStream.is_open() ) {
		std::cerr << "Error open output file" << std::endl;
		inputStream.close();
		return EXIT_FAILURE;
	}

	try {
		if( 0 == strcmp(argv[::DATA_TYPE_ARGUMENT], "-i") ) {
			sortAndWrite<int>(inputStream, outputStream, sortMode);
		} else if( 0 == strcmp(argv[::DATA_TYPE_ARGUMENT], "-f") ) {
			sortAndWrite<double>(inputStream, outputStream, sortMode);
		} else if( 0 == strcmp(argv[::DATA_TYPE_ARGUMENT], "-s") ) {
			sortAndWrite<std::string>(inputStream, outputStream, sortMode);
		} else {
			std::cerr << "Error in data type" << std::endl;
		}
	} catch( std::exception& e ) {
		std::cerr << e.what() << std::endl;
	}

	inputStream.close();
	outputStream.close();
	

	return EXIT_SUCCESS;
}